dave_wwid, на событии Юнит Атакован возможны баги и утечки. Не лучше ли на событии получает урон?
Я думаю, что вы правы...
Yuru13, вам следует выбрать событие Specific Unit Event, а в нём Получает урон (Damage taken), и создать глобальную переменную для критующего. Далее следует конвертировать триггер в текст и заменить место под Юнита в событии на некую глобальную переменную(Таковую создать через другой триггер типа Событие: Юнит атакован Условие: Атакующий = глобальной переменной атакующий Действие: присвоить свободной глобальной переменной значение атакованный юнит). Также вам пригодится Dmage Source (пишется кое-где вместо triggering unit). Damage source - это тот, кто нанёс урон. В условии пишем, чтобы Damage source соответствовал переменной.(Ну а в переменную его можно засунуть при инициализации карты, или вовсе не сувать, если он будет на карте изначально). Действия же добавляете ваши.
P.S. Конвертированием триггера лучше заняться после добавленных действий. И помните, что Нужно как минимум 2 глобальные переменные типа юнит и 2 триггера.
Недостатки способа
Данный способ будет работать только если у вас на карте одни юнит, имеющий криты с кулдауном, и если этот юнит атакует за раз одну цель... В противном случае придётся создавть локальные переменные вместо глобальных, и в одном триггере. Или же созданные переменные отметить как массивы и создать счётчик для этих переменных (Но и в таком случае не без багов и т.п.)
Ну решается всё довольно тривиально
Юнит атакован
приказ атакующего юнита не равен "атаковать"
б.е. - приказать атакующий ПКМ атакованного
При первой атаке произойдёт небольшая потеря времени, т.к. получив при каз юнит заново начнёт анимацию атаки. Зато орб будет прокать.
Алсо если приказать юниту перейти нападая на противников (триггерно или ручками) - приказ юнита будет какой-надо и орб будет срабатывать.
WiLian, так я имел в виду два триггера..
Вот так: xgm.guru/files/100/198847/comments/366316/Give.w3m
Скопируй 2 триггера и переменную-массив юнитов Selected в свою карту.
Тут даже без проверки получается вроде.
Если нужно больше игроков, чем 4 - то добавляй события с ними.
1 - очень просто, запомнил номер владельца в переменную при касте, через нужное время возвращаешь бывшего
2 - тоже очень просто, делаешь заклинание на основе пустышки в области, можно на основе канала, триггерно выделяешь всех врагов вокруг точки каста и меняешь им владельца с нужным графическим эффектом
Кидаешь её файлы в папку с игрой, запускаещь игру, ждешь внедрения (жмешь ок), запускаешь карту. Потом в логах JassSpy.txt смотришь на каком месте у тебя прервалась игра.
По коду честно говоря ничего не понятно. Но в отлове урона это обычная ошибка, когда урон наносится внутри триггера, отлавливающего урон или если он вызывает действия которые наносят урон и снова вызывают этот триггер. Бесконечная рекурсия в общем роняет игру.
map_maiker, какой то глупый код, у тебя если нет аргумента dummy - то идет обрыв потока, ибо обращение к пустой переменной.
function DummyTargetCast takes unit cast, unit targ, integer spellid, integer order returns nothing
local unit dummy = CreateUnit( GetOwningPlayer(cast), 'hdum', GetUnitX(targ), GetUnitY(targ), bj_UNIT_FACING )
call SetUnitPathint( dummy, false )
call UnitAddAbility( dummy, spellid )
call UnitApplyTimedLife( dummy, 'BTLF', 5.00 )
call UnitShareVision( targ, GetOwningPlayer(cast). true )
call IssueTargetOrder( dummy, order, targ )
call UnitShareVision( targ, GetOwningPlayer(cast). false )
set dummy = null
endfunction
// пример использования
call DummyTargetCast( GetSpellAbiliutyUniut(), GetSpellTargetUnit(), 'Ahtb', OrderId("thunderbolt"))
Код не универсальный, да и вовсе можно круче и оптимальнее, ты совершенно не учитываешь следующие вещи:
выгоднее юзать специально заготовленные глобальные переменные чтобы хранить того же даммика.
даммик может мешатся, толкатся, желательно создавать его в позиции цели, и убирать карту путей.
не стоит ставить короткое время жизни даммикам, если они наносят урон, может случится конфуз - кто убил не известно
Даммик может не видеть цель, поэтому нужно создавать даммика за врага (но в настройках способности указать цели - союзники) что катит только для спеллов не наносящих урон, или делать SharedVision.
В "графика -нужная анимация" ничего не менял?
Вполне возможно, что для этой пассиви она по дефолту стенд ченннел проигрывает или попросту добавляет тег ченнел.
Ну это смешно.
Всё дело в ОС. После того как Windows 10 build 1607 вышел из режима смены пользователя, запустил карту из этого комментария, и анимации поломались. Перезагрузил компьютер, анимации стали верными.
Проблема была в том, что те две штуки, что показаны на скрине, не были прикреплены ни к какой кости. Тупо висели в воздухе проще говоря.
Анимация Stand тож сделал как надо.
Если первый кадр анимации правильный, попробуйте удалить последний кадр анимации, потом скопировать кадр в её начале (Именно через команду "Кадры" - "Копировать (Ctrl + C)" !) и вставить его в конец. То же самое проделать с другой анимацией (Stand 2). Если это не поможет, тогда надо детально смотреть саму модель, что с ней не так. И ещё советую сохранять промежуточные версии модели, чтоб можно было сделать "откат", если возникнут ошибки.
Невозможно дать тимколор декорации. Можно ставить нужный тимколор в 3D-редакторе mdlvis, либо делать декорации из зданий, которым дана способность Москиты (Aloc).
Ставишь юниту в разделе Бой - Атаки на Нет, потом делаешь две способности на базе одной из сфер (например Предмет: электрическая атака), у одной из них Включен индекс атаки - 1, у другой - 2. Добавляешь первую способность юниту в РО. Когда тебе нужно изменить дальность атаки - удаляешь ту способность сферы, которая есть у юнита и добавляешь другую. Правда при этом не будет видно иконки атаки.
так это самый простой вариант там приказ сам отлавливать .а не замах я так к примеру написал ( но гемора с проверками будет много мне кажется )
можно еще посути менять дистанцию получение приказа на отаку менять у юнита
call SetUnitAcquireRangeBJ( gg_unit_Hblm_0000, 100.00 )
кароч сделал только до ума довести нужно но вроде все работает.
Для увеличения дальности атаки используют улучшение на основе длинностволых мушкетов. Добавить всем героям это улучшение после чего при получении предмета выставляется уровень улучшения функцией SetPlayerTechResearched
Баг абилки
исправляется с помощью тригга - добавляем анимационный таг, счетчик для количества ударов и даем руну на морф с другим типом атаки\бонус к урону\...
само собой абилку заменяем другой, можно на основе канала
Юнит атакует, ждать время точки повреждения, потом ждать расстояние до цели атакованного юнита, деленное на скорость снаряда. Но промах учитываться не будет конечно. Можно как-то попробовать через юнит получает урон.
Сделать области (безопасные зоны).
Периодическое событие - каждую секунду.
Условие - время > 6.00 и время < 18.00.
Действие - если герой не в области 1 или герой не в области 2 и т. д., то уменьшить жизнь на 85.00.
событие урона показывает сколько нанесет урона сейчас, но урон еще не пришел. урон происходит через 0.00 сек.
у вас может быть в этот момент максимальный запас здоровья (например у курицы 10 хп). А урон противника получается слишком большим.
раскрыть
2.1. Манипуляциями с хп через команды типа set life of unit вы не всегда можете наперед подправлять. Тк хп может упереться в лимит запаса здоровья юнита. А получаемый урон больше чем запас, и юнит умрет.
2.2. Можно сделать юнита временно неуязвимым, тогда атака не срабатывает
2.3.поэтому самое идеальное даем абилку с максимальным запасом здоровья с 999999к хп. Юнит точно не умрет от урона.
после таймера 0.00 сек убираем абилу и подправляем как надо.
ты можешь делать проверки сколько очков осталось на поглощение
Nemezid, это незаметно, тк все происходит очень быстро.
есть событие - юнит получает урон. в нём отслеживается как жертва, так и наносящий урон. можно хоть через хэш, хоть через структуру Юнита записывать всё, что угодно. Кто от кого конкретно сколько получил урона, кто кому сколько нанёс, сколько провисел на ком-то бафф яда и т.п. (Сначала был loop, а теперь периодический триггер). Каждые N секунд, перебираешь всех юнитов в массиве или списке, и отслеживаешь всё, что надо.
Структура - Unit. У неё есть двойной список с юнитами и уроном от яда (полученным или нанесённым - зависит от того, у кого будет этот список - у жертв или у тех, кто наносит яд). Типа DoubleList. В DoubleList есть элементы DoubleElement. В каждом таком элементе записаны unit и real (урон от яда от этого юнита). При получении урона от яда перебирается список, если юнит уже есть, урон от него (или ему) прибавляется. Если нет, то создаётся новый элемент с новым юнитом.
Периодически у нужных юнитов эти списки перебираются. Всё.
Поскольку его не пугает наличие большого влияния промахов на геймплей - скорее всего он делает рпг. Имхо в рпг всегда клево смотрятся тексттаги полученного урона, для создания которых необходимы триггеры на отлов получения урона. А отлавливаемый урон - можно и прохилить.
Для прохила(и вообще всех манипуляций с задержкой в 0.00 сек) лично я юзаю такие костыли:
Либа здесь только для доп табуляции. Я за чистый жасс + дефайны.
library ZeroTimeEvent
globals
constant integer ZTEArraySize = 64//Even 32 is alot, 64 is too much! Exactly what I need!
timer Zero//Used for 0. sec uses
integer ZTECurrent = 0
unit array ZTEUnits[ZTEArraySize]
integer array ZTEIntegers[ZTEArraySize]
real array ZTEReals[ZTEArraySize]
trigger array ZTETriggers[ZTEArraySize]
endglobals
function ZeroTimeEvent takes nothing returns nothing
loop
set ZTECurrent = ZTECurrent - 1
call TriggerExecute( ZTETriggers[ZTECurrent] )
exitwhen ZTECurrent < 1
endloop
endfunction
#define ZTEAddUnit(u) = {
set ZTEUnits[ZTECurrent] = u
}
#define ZTEAddInteger(i) = {
set ZTEIntegers[ZTECurrent] = i
}
#define ZTEAddReal(r) = {
set ZTEReals[ZTECurrent] = r
}
#define ConfirmZTE(trig) = {
set ZTETriggers[ZTECurrent] = trig
set ZTECurrent = ZTECurrent + 1
call TimerStart( Zero, ZeroTime, false, function ZeroTimeEvent )
}
endlibrary
что-то не вижу на скрине как вы пытаетесь запихнуть в if/then/else. Почему должен угадывать
Предположение: ошибка - локальные переменные объявляются всегда первыми. Если там будет какое-то другое действие, а объявление локалок ниже, то это ошибка. Ты вперед, наверное, поставил действие "if/then/else", а потом начал объявлять что-то там,
правильно
local unit u
if (условие) then
действие
endif
не правильно
if (условие) then
local unit u
endif
Локалки вначале функции всегда объявляются. Можете в код конвентировать и посмотреть.
Есть функция проверки кол-ва ловкости героя, при этом можно посмотреть сколько ловкости от характеристик и сколько от предметов, исходя из кол-ва ловкости вручать предметные абилки на атаку.
Самое простое - апгрейды, триггерно повышать уровень улучшения которое будет действовать на героя, увы это не идеальный вариант, но один из самых просты. Так же вручать способности предметов на регенерацию здоровья \ маны.
Напрямую - никак, есть место только под 5 способностей. Делать свою систему прокачки способностей из спеллбука или какие либо еще способы, на подобии рпгшных карт.
Событие юнит получает урон регистрируется на конкретного юнита.
Для того что бы отлавливать урон по цели твоего "щита", нужно создать для цели (т.е. для того юнита, на которого накладывают щит) отдельное событие на получением им урона. И делать это надо именно в тот момент, когда ты накладываешь щит.
Для этого есть функция добавить событие в триггер, в ней можно указать конкретного юнита и само событие получения урона. Дальше тебе придётся только лишь определить был ли юнит в момент получения урона под действием "щита" и дальше блокировать урона (восстанавливать хп юнита).
Так же надо отметить момент, что если ты для юнита создаёшь больше ОДНОГО события на получение урона - они будут работать каждый сам по себе (т.е. при получении урона 1 раз, будут срабатывать 2 события, и триггер будет срабатывать ДВА раза = больше события и больше срабатываний в один момент времени).
Для этого надо маркеровать юнитов, для которых создаётся событие на получение урона (например заносить их в группу юнитов, а перед этим проверять есть ли юнит в этой группе).
Потому что огромный Нестандартные объекты может тысяч или больше или Спелл герой до 100 уровень.
из них 60 загрузка просто висит на 1/5.
Если нетак? Проверь если есть файлы war3map.j папка Game\WarcraftIII, надо удалить файл. очень давно тоже 1 раз что за вылет или неправильно выполняет триггер.
Есть способы ускорить загрузку карты не экономя в редакторе объектов
Есть Widgetizer, там очень быстрая загрузка игра, но плохо работает спелл или текст.
Невозможно дать тимколор декорации. Можно ставить нужный тимколор в 3D-редакторе mdlvis, либо делать декорации из зданий, которым дана способность Москиты (Aloc).
Какие именно эффекты в модели дублировал, а какие создал с нуля? Надо попытаться сравнить эти эффекты, сохранив модель в формат mdl и открыв в блокноте. Может быть дело даже не в самих эффектах, а в упоминании где-то их ID.
Есть вариант оперировать при помощи морфа, превращая воздушную единицу в наземную. Что-то вроде имитировании посадки на аэродром. это можно сделать через отлов приказов с проверкой расстояния между единицей и зданием, а также при выгрузке просто отлавливать выгруженную единицу, и морфить обратно влетающую.
Зверобойщик, во-первых, триггеры варика по сути представляют собой упрощённое программирование, ими делают свой движок игры, если нужно, например, симулятор гонок, шутера, РПГ с видом от третьего лица, даже авиасимулятор и прочее. Если ты в них не разбираешься, либо разбираешься очень плохо, то более половины своих идей не сможешь реализовать. Говорю по жизненному опыту, в детстве научился в редакторе карт к Героям 3 делать полноценные карты и кампании без триггеров, думал, что и к остальным играм так легко смогу что-то делать, но не тут-то было!
Во-вторых, возможность носить несколько видов оружия у юнита ты преподносишь как нечто обязательное, но если для людей и орков это ещё будет нормально, то вурдалаки нежити сражаются только своими когтями, а хрупкие лучницы ночных эльфов не будут в руки тяжеленные молоты брать, чтобы померяться силой с мужиками в ближнем бою. Помимо отсутствия в войнах древности летающих юнитов, есть ли там водоплавающие? Это всё проблемы, которые ты хочешь на потом отложить, но это те проблемы, которые нужно сразу как-то решить, чтобы понять урезанность своей идеи, либо даже полную невозможность осуществления.
В-третьих, почему-то только четыре картинки отображается, судя по которым, способности в войнах древности в целом имеют свои аналоги в варике, но опять же не те, которые выше упомянул. А упомянул не случайные способности, а такие, которые затруднительно было бы реализовать, если в игре нет аналогов. Как реализуешь поднятие скелетов из трупа, например? Оно обязательно нужно - это ключевая особенность нежити.
В-четвёртых, под устройством файлов подразумевал, что ты умеешь открывать архивы игры, форматы изображений и прочих файлов, а также знаешь, почему там что-то сделано так, а не иначе. Например, в варике текстуры почвы представляют собой изображение 256х512 или 256х256 в зависимости от того, будет ли текстура накладываться сверху на другие при соприкосновении, либо всегда будет снизу. Если будет накладываться, то левая часть изображения поделена на зоны 4х4, в каждой из которых указан вариант для разных вариантов соприкосновения текстур, в правой части тоже зоны 4х4, где каждый кусочек полноценной текстуры земли имеет небольшие изменения, чтобы в редакторе почва получалась разнообразной (где-то камень, где-то кочка, где-то полевые цветы), а не наскучивала неестественностью игроку. То есть нельзя просто любое изображение туда поставить, в игре будет смотреться шахматной доской, а не единым пространством.
В-пятых, если почитаешь про этот проект, то изначально Armies of Azeroth не делались под Starcraft 2, а были обновлением моделек для варика под названием Reborn или Resurrection, запамятовал точное название. Мотивы их перехода на другой движок мне неизвестны, но вроде как это было одним из условий объединения двух или более проектов (вроде бы трёх), которые по отдельности вряд ли бы были доведены до конца. Это к тому, что идеей создания новых моделек всерьёз горело множество талантливых людей, и они смогли довести дело до конца, лишь скооперировавшись на международном уровне. А у тебя единомышленников, насколько понимаю, нет?
В-шестых, почти не играю, не хочется касаться нового, сейчас акцент в играх на графику и мультиплеер смещён, либо казуальщину, а мне нравится наслаждаться глубоким сюжетом в одиночку) P. S. Даже не трать время и энергию на уговоры.
В-седьмых, переносные или подвозные лестницы, тут не столь принципиально. В зависимости от модели лестницы будет своя реализация. В твоём случае потребуется модель переносчика лестницы с анимацией, как он её ставит. Потом лестница у него исчезает и сразу появляется на её месте декорация лестницы из категории Мосты и подъёмы. Тут долго всё это описывать, скажу только, что поднимается по ней юнит гладко, проверял много раз)
Поиграйся с орбэффектами, добавляя в разрешённые цели необходимую клиссификацию. А вообще, просто поступи так:
Атака есть изначально, но при ударе юнитом по камню или дереву, проверка, имеет ли он кирку, и если да, тогда ролить переменную от N до N, и если равно N - создать такой то ресурс.
Можно также сделать систему с уровнем кирки(ну типа деревянная каменная железная алмазная окда), и по уровню кирки определять коилчество последовательностей "Иначе": Роллить первое число от 1 до 100 - камень. Если не выпал, но кирка у тебя выше деревянной - Роллить от 1 до 200 - железо. Если не выпало, но кирка выше каменной - роллить от 1 до 1000 - аметист, и т.д.
Daniil33, нет, надо через if-then-else проверять, что камень там еще "живой", и если нет, создавать новый и заносить в переменную.
И так циклом для каждой области
Сами области в массив заносить при инициализации карты
Если запускаемая сложность главы отличается от стандартной, то оставить так, как есть, а если нет - то попытаться считать то, что было записано в предыдущей главе (если не записано - сбросить к стандартной).
Вообще, сама функция не запускает уровень с какой-то сложностью. Она просто задает значение глобальной переменной:
Код функции
function SetNextLevelBJ takes string nextLevel returns nothing
if (nextLevel == "") then
set bj_changeLevelMapName = null
else
set bj_changeLevelMapName = nextLevel
endif
endfunction
Если копать глубже, то вся проблема здесь:
Код функций
function CustomVictoryOkBJ takes nothing returns nothing
if bj_isSinglePlayer then
call PauseGame( false )
// Bump the difficulty back up to the default.
call SetGameDifficulty(GetDefaultDifficulty())
endif
if (bj_changeLevelMapName == null) then
call EndGame( bj_changeLevelShowScores )
else
call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
endif
endfunction
function CustomVictoryQuitBJ takes nothing returns nothing
if bj_isSinglePlayer then
call PauseGame( false )
// Bump the difficulty back up to the default.
call SetGameDifficulty(GetDefaultDifficulty())
endif
call EndGame( bj_changeLevelShowScores )
endfunction
Если интересно, откуда все это берется, то нужно посмотреть устройство функции CustomVictoryBJ и все вызовы, следующие из нее.
Чтобы править проблему без создания костылей на кэше, то придется переписать близовскую функцию под себя (без сбрасывания сложности), а потом использовать ее вместо оригинальной в своей кампании (удобства ради можно использовать дефайн на cJass).
Причина: причин было много, а я искал лишь одну
Самыми распространёнными оказались элементарные ошибки в коде, отсутствие параметров, параметры не того типа данных (привет динамическая типизация) или лишние параметры, из за чего происходили "рандомные рассинхроны при обрыве потока"
Огромное спасибо пользователю prog, что откликнулся и смог найти ошибки, а нашёл он их при помощи языкового сервера sumneko lua для VScode
способности кодоя (ээх посмотрел бы): Проглотить 'Adev' - проглатывает указанное существо и переваривает, нанося урон указанный в скиле "Еда" Еда 'Advc' - здесь можно указать сколько урона наносит перевариваемым существам в секунду. И сколько может вместить в желудок существ.
Эти способности друг с другом связаны
Нет ошибки. Максимальный уровень монстров применяется только для нейтрально-враждебных жертв зверя. То есть, если у жертвы будет какая-либо раса, в редакторе объектов, отличная от "монстров", то ограничения уровня применяться не будут.
"Набор звуков" нельзя сделать через триггеры, но можно попробовать через импорт файлов заменить стандартные файлы в уже существующих наборах.
Для этого импортируемому файлу надо прописать путь заменяемого.
Это особенность патча 1.30, на 1.26 всё нормально с этим. Может быть попробовать поменять приоритет кампании в файле priority, в статье про mix-архив это подробнее описано.
» WarCraft 3 / Замена атаки на способность
» WarCraft 3 / Подчинение
» WarCraft 3 / Перенос ландшафта
» WarCraft 3 / Dummy unit
» WarCraft 3 / Баг в анимации Stand
» WarCraft 3 / Как сделать тим колор
» WarCraft 3 / Помощь
» WarCraft 3 / дальность атаки
» WarCraft 3 / Герой не наносит урон
» WarCraft 3 / ИИ
» WarCraft 3 / Свечение героев в рефорже
» WarCraft 3 / бонусы скорости атаки от ловкости
» WarCraft 3 / Команды триггера
» WarCraft 3 / Нестандартная декорация
» WarCraft 3 / Проблема с источниками частиц
» WarCraft 3 / Транспортное средство
» WarCraft 3 / Добыча камня
» WarCraft 3 / Как убрать выбор игрока при запуске карты?
» WarCraft 3 / Проглотить
» WarCraft 3 / Кастомная озвучка проблемы